package org.agony2d.gpu.supportClasses.textures {
	import flash.display.BitmapData;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.textures.Texture;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.getTimer;
	
	import org.agony2d.core.agony_internal;
	import org.agony2d.debug.Logger;
	import org.agony2d.gpu.core.AAManager;
	import org.agony2d.gpu.core.NodeAA;
	
	use namespace agony_internal;
	
public class FullTexture extends TextureProxy {
	
	public function FullTexture( name:String ) {
		m_name = name
	}
	
	agony_internal function parseAtlasXml( atlasXml:XML ) : void {
		var sub:XML
		var region:Rectangle, frame:Rectangle
		var frameX:Number, frameY:Number, frameWidth:Number, frameHeight:Number
		
		for each (sub in atlasXml.SubTexture) {
			frameX       =  parseFloat(sub.attribute("frameX"))
			frameY       =  parseFloat(sub.attribute("frameY"))
			frameWidth   =  parseFloat(sub.attribute("frameWidth"))
			frameHeight  =  parseFloat(sub.attribute("frameHeight"))
			region       =  new Rectangle(parseFloat(sub.attribute("x")), parseFloat(sub.attribute("y")), parseFloat(sub.attribute("width")), parseFloat(sub.attribute("height")))
			frame        =  (frameWidth > 0 && frameHeight > 0) ? new Rectangle(frameX, frameY, frameWidth, frameHeight) : null
			this.addRegion(sub.attribute("name"), region, frame)
		}
	}
    
	agony_internal function reset( data:BitmapData, mipmapEnabled:Boolean ) : void {
		var width_A:int, height_A:int
		var width_B:int, height_B:int
		var level:int
		var BA:BitmapData
		
		width_A       =  data.width
		height_A      =  data.height
		width_B       =  getNextPowerOfTwo(width_A)
		height_B      =  getNextPowerOfTwo(height_A)
		m_rawTexture  =  AAManager.g_context3d.createTexture(width_B, height_B, Context3DTextureFormat.BGRA, false)
		if (width_B > width_A || height_B > height_A) {
			BA = new BitmapData(width_B, height_B, true, 0x0)
			BA.copyPixels(data, data.rect, new Point)
			data = BA
			m_realityWidth = width_A
			m_realityHeight = height_A
			m_fullWidth = width_B
			m_fullHeight = height_B
		}
		else {
			m_fullWidth = m_realityWidth = width_B
			m_fullHeight = m_realityHeight = height_B
		}
		
		var t:int = getTimer()
		
		m_rawTexture.uploadFromBitmapData(data)
		
		Logger.reportMessage(this, "( " + m_name + " ) upload texture time : " + (getTimer() - t))
		
		if (mipmapEnabled && data.width > 1 && data.height > 1) {
			width_A  = data.width  >> 1
			height_A = data.height >> 1
			BA = new BitmapData(width_A, height_A, true, 0x0)
			cachedRect.setTo(0, 0, width_A, height_A)
			cachedMatrix.setTo(.5, 0, 0, .5, 0, 0)
			while (width_A >= 1 || height_A >= 1) {
				BA.fillRect(cachedRect, 0x0)
				BA.draw(data, cachedMatrix, null, null, null, true)
				m_rawTexture.uploadFromBitmapData(BA, ++level)
				width_A  >>= 1
				height_A >>= 1
				cachedRect.setTo(0, 0, width_A, height_A)
				cachedMatrix.scale(.5, .5)
			}
		}
	}
	
	[Inline]
	final agony_internal function addRegion( name:String, region:Rectangle, frame:Rectangle ) : void {
		if (m_regionMap[name] || name == FULL_TEX) {
			Logger.reportError(this, "addRegion", "repeated region name [ " + name + " ]...!!")
		}
		m_regionMap[name] = new RegionTexture(this, region, frame)
		//Logger.reportMessage("TextureManager", "region tex ( " + name + " )..added to ( " + m_name + " )")
	}
	
	[Inline]
	final agony_internal function getRegion( name:String ) : TextureProxy {
		return (name == FULL_TEX) ? this : m_regionMap[name]
	}
	
	
	agony_internal static const FULL_TEX:String = "fullTex"
	
	agony_internal var m_regionMap:Object = {}
	agony_internal var m_mipmapEnabled:Boolean
	agony_internal var m_name:String
}
}